#include <gtest/gtest.h>
#include "Thread/TaskQueue.h"
#include <thread>
#include <atomic>
#include <vector>

// - BasicPushAndGet : 测试基本的任务推送和获取功能
// - PushFirst : 测试优先推送任务的功能
// - MultiThreadAccess : 测试多线程访问下的线程安全性
// - QueueSize : 测试队列大小功能
// - PushExit : 测试退出信号功能

using namespace toolkit;
using namespace std;

class TaskQueueTest : public testing::Test {
protected:
    TaskQueue<std::function<void()>> queue;
};

TEST_F(TaskQueueTest, BasicPushAndGet) {
    bool taskExecuted = false;
    
    queue.push_task([&]() {
        taskExecuted = true;
    });
    
    std::function<void()> task;
    ASSERT_TRUE(queue.get_task(task));
    task();
    
    EXPECT_TRUE(taskExecuted);
}

TEST_F(TaskQueueTest, PushFirst) {
    vector<int> executionOrder;
    
    queue.push_task([&]() {
        executionOrder.push_back(2);
    });
    
    queue.push_task_first([&]() {
        executionOrder.push_back(1);
    });
    
    std::function<void()> task1, task2;
    ASSERT_TRUE(queue.get_task(task1));
    ASSERT_TRUE(queue.get_task(task2));
    
    task1();
    task2();
    
    ASSERT_EQ(executionOrder.size(), 2);
    EXPECT_EQ(executionOrder[0], 1);
    EXPECT_EQ(executionOrder[1], 2);
}

TEST_F(TaskQueueTest, MultiThreadAccess) {
    const int taskCount = 100;
    atomic_int executedCount(0);
    
    thread producer([&]() {
        for (int i = 0; i < taskCount; ++i) {
            queue.push_task([&]() {
                ++executedCount;
            });
        }
    });
    
    thread consumer([&]() {
        std::function<void()> task;
        while (executedCount < taskCount) {
            if (queue.get_task(task)) {
                task();
            }
        }
    });
    
    producer.join();
    consumer.join();
    
    EXPECT_EQ(executedCount.load(), taskCount);
}

TEST_F(TaskQueueTest, QueueSize) {
    EXPECT_EQ(queue.size(), 0);
    
    queue.push_task([]() {});
    queue.push_task([]() {});
    
    EXPECT_EQ(queue.size(), 2);
    
    std::function<void()> task;
    queue.get_task(task);
    
    EXPECT_EQ(queue.size(), 1);
}

TEST_F(TaskQueueTest, PushExit) {
    atomic_int executedCount(0);
    atomic_bool shouldExit(false);
    const int taskCount = 5;
    
    // 先添加5个正常任务
    for (int i = 0; i < taskCount; i++) {
        queue.push_task([&]() {
            ++executedCount;
        });
    }

    thread consumer([&]() {
        std::function<void()> task;
        while (!shouldExit) {
            if (queue.get_task(task)) {
                task();
            }
        }
    });

    // 等待所有任务完成
    while (executedCount.load() < taskCount) {
        this_thread::sleep_for(chrono::milliseconds(10));
    }

    // 发送退出信号
    queue.push_exit(1);
    shouldExit = true;
    
    consumer.join();

    EXPECT_EQ(executedCount.load(), taskCount);
}